import { Color, ColorScheme, ColorSchemeType } from '@/types';
import { ColorUtils } from '@/utils/color';
import { StorageService } from './storage';

/**
 * 色彩推荐引擎
 * 基于色彩理论、用户偏好和流行趋势生成色彩搭配推荐
 */
export class ColorRecommendationEngine {
  private static instance: ColorRecommendationEngine;

  private constructor() {}

  public static getInstance(): ColorRecommendationEngine {
    if (!ColorRecommendationEngine.instance) {
      ColorRecommendationEngine.instance = new ColorRecommendationEngine();
    }
    return ColorRecommendationEngine.instance;
  }

  /**
   * 生成互补色搭配
   */
  async generateComplementaryColors(baseColor: Color, count: number = 3): Promise<Color[]> {
    const complementary = ColorUtils.getComplementary(baseColor);
    const variations: Color[] = [complementary];

    // 生成互补色的明度和饱和度变化
    for (let i = 1; i < count; i++) {
      const lightnessDelta = (i % 2 === 0 ? 1 : -1) * (10 + i * 5);
      const saturationDelta = (i % 2 === 0 ? -1 : 1) * (5 + i * 3);
      
      const variation = ColorUtils.adjustLightness(
        ColorUtils.adjustSaturation(complementary, saturationDelta),
        lightnessDelta
      );
      
      variations.push(variation);
    }

    return variations.slice(0, count);
  }

  /**
   * 生成类似色搭配（相邻色）
   */
  async generateAnalogousColors(baseColor: Color, count: number = 4): Promise<Color[]> {
    const colors: Color[] = [];
    const stepSize = 30; // 30度间隔
    const hsl = baseColor.hsl;

    for (let i = 1; i <= count; i++) {
      // 交替生成左右两侧的相邻色
      const direction = i % 2 === 1 ? 1 : -1;
      const steps = Math.ceil(i / 2);
      const newHue = (hsl.h + direction * stepSize * steps + 360) % 360;
      
      // 轻微调整饱和度和明度以增加变化
      const saturation = Math.max(20, Math.min(100, hsl.s + (Math.random() - 0.5) * 20));
      const lightness = Math.max(20, Math.min(80, hsl.l + (Math.random() - 0.5) * 20));
      
      colors.push(ColorUtils.fromHsl(newHue, saturation, lightness));
    }

    return colors;
  }

  /**
   * 生成三元色搭配
   */
  async generateTriadicColors(baseColor: Color): Promise<Color[]> {
    const triadicColors = ColorUtils.getTriadic(baseColor);
    
    // 为每个三元色生成一个变化版本
    const variations: Color[] = [];
    triadicColors.forEach(color => {
      variations.push(color);
      // 生成明度变化版本
      const lighter = ColorUtils.adjustLightness(color, 15);
      const darker = ColorUtils.adjustLightness(color, -15);
      variations.push(lighter, darker);
    });

    return variations;
  }

  /**
   * 生成四元色搭配
   */
  async generateTetradicColors(baseColor: Color): Promise<Color[]> {
    return ColorUtils.getTetradic(baseColor);
  }

  /**
   * 生成单色调搭配
   */
  async generateMonochromaticColors(baseColor: Color, count: number = 5): Promise<Color[]> {
    return ColorUtils.getMonochromatic(baseColor, count);
  }

  /**
   * 基于用户历史偏好生成个性化推荐
   */
  async generatePersonalizedRecommendations(
    baseColor: Color, 
    userHistory?: ColorScheme[]
  ): Promise<Color[]> {
    try {
      // 如果没有提供历史记录，从存储中获取
      const history = userHistory || await StorageService.getColorSchemes();
      
      if (history.length === 0) {
        // 没有历史记录时，返回基础推荐
        return this.generateBasicRecommendations(baseColor);
      }

      const preferences = this.analyzeUserPreferences(history);
      
      return this.generateColorsBasedOnPreferences(baseColor, preferences);
    } catch (error) {
      console.error('Failed to generate personalized recommendations:', error);
      return this.generateBasicRecommendations(baseColor);
    }
  }

  /**
   * 生成流行趋势推荐
   */
  async generateTrendingRecommendations(baseColor: Color): Promise<Color[]> {
    // 模拟流行色彩趋势数据
    const trendingPalettes = this.getTrendingPalettes();
    
    return this.findSimilarColorsInTrends(baseColor, trendingPalettes);
  }

  /**
   * 生成季节性推荐
   */
  async generateSeasonalRecommendations(baseColor: Color): Promise<Color[]> {
    const currentMonth = new Date().getMonth();
    const season = this.getCurrentSeason(currentMonth);
    
    return this.generateSeasonalColors(baseColor, season);
  }

  /**
   * 生成基于情绪的推荐
   */
  async generateMoodBasedRecommendations(
    baseColor: Color, 
    mood: 'energetic' | 'calm' | 'warm' | 'cool' | 'professional' | 'playful'
  ): Promise<Color[]> {
    const colors: Color[] = [];
    
    switch (mood) {
      case 'energetic':
        colors.push(...this.generateEnergeticColors(baseColor));
        break;
      case 'calm':
        colors.push(...this.generateCalmColors(baseColor));
        break;
      case 'warm':
        colors.push(...this.generateWarmColors(baseColor));
        break;
      case 'cool':
        colors.push(...this.generateCoolColors(baseColor));
        break;
      case 'professional':
        colors.push(...this.generateProfessionalColors(baseColor));
        break;
      case 'playful':
        colors.push(...this.generatePlayfulColors(baseColor));
        break;
    }
    
    return colors;
  }

  /**
   * 根据色彩理论类型生成推荐
   */
  async generateBySchemeType(
    baseColor: Color, 
    schemeType: ColorSchemeType,
    count: number = 4
  ): Promise<Color[]> {
    switch (schemeType) {
      case 'complementary':
        return this.generateComplementaryColors(baseColor, count);
      case 'analogous':
        return this.generateAnalogousColors(baseColor, count);
      case 'triadic':
        return this.generateTriadicColors(baseColor);
      case 'tetradic':
        return this.generateTetradicColors(baseColor);
      case 'monochromatic':
        return this.generateMonochromaticColors(baseColor, count);
      default:
        return this.generateBasicRecommendations(baseColor);
    }
  }

  // 私有辅助方法

  /**
   * 分析用户偏好
   */
  private analyzeUserPreferences(history: ColorScheme[]): UserPreferences {
    const allColors = history.flatMap(scheme => scheme.colors);
    const schemeTypes = history.map(scheme => scheme.type);
    
    // 分析最常用的色相范围
    const hueFrequency: { [range: string]: number } = {};
    allColors.forEach(color => {
      const hueRange = this.getHueRange(color.hsl.h);
      hueFrequency[hueRange] = (hueFrequency[hueRange] || 0) + 1;
    });
    
    // 分析饱和度和明度偏好
    const saturation = allColors.reduce((sum, color) => sum + color.hsl.s, 0) / allColors.length;
    const lightness = allColors.reduce((sum, color) => sum + color.hsl.l, 0) / allColors.length;
    
    // 分析最常用的搭配类型
    const typeFrequency: { [type: string]: number } = {};
    schemeTypes.forEach(type => {
      typeFrequency[type] = (typeFrequency[type] || 0) + 1;
    });
    
    return {
      preferredHues: Object.keys(hueFrequency).sort((a, b) => hueFrequency[b] - hueFrequency[a]),
      averageSaturation: saturation,
      averageLightness: lightness,
      preferredSchemeTypes: Object.keys(typeFrequency).sort((a, b) => typeFrequency[b] - typeFrequency[a])
    };
  }

  /**
   * 基于偏好生成颜色
   */
  private generateColorsBasedOnPreferences(baseColor: Color, preferences: UserPreferences): Color[] {
    const colors: Color[] = [];
    const baseHsl = baseColor.hsl;
    
    // 基于偏好的色相生成颜色
    preferences.preferredHues.slice(0, 3).forEach(hueRange => {
      const targetHue = this.getHueFromRange(hueRange);
      const saturation = (preferences.averageSaturation + baseHsl.s) / 2;
      const lightness = (preferences.averageLightness + baseHsl.l) / 2;
      
      colors.push(ColorUtils.fromHsl(targetHue, saturation, lightness));
    });
    
    return colors;
  }

  /**
   * 获取基础推荐
   */
  private generateBasicRecommendations(baseColor: Color): Color[] {
    // 生成互补色和类似色的组合
    const complementary = ColorUtils.getComplementary(baseColor);
    const analogous = ColorUtils.getAnalogous(baseColor, 2);
    
    return [complementary, ...analogous];
  }

  /**
   * 获取流行色彩趋势（模拟数据）
   */
  private getTrendingPalettes(): Color[][] {
    return [
      // 2024年流行色组合（示例）
      [
        ColorUtils.fromHex('#FF6B6B'), // 珊瑚红
        ColorUtils.fromHex('#4ECDC4'), // 青绿色
        ColorUtils.fromHex('#45B7D1'), // 天蓝色
        ColorUtils.fromHex('#96CEB4')  // 薄荷绿
      ],
      [
        ColorUtils.fromHex('#A8E6CF'), // 淡绿色
        ColorUtils.fromHex('#FF8B94'), // 粉红色
        ColorUtils.fromHex('#FFD93D'), // 金黄色
        ColorUtils.fromHex('#6BCF7F')  // 草绿色
      ],
      [
        ColorUtils.fromHex('#B4A7D6'), // 薰衣草紫
        ColorUtils.fromHex('#D4A574'), // 暖橙色
        ColorUtils.fromHex('#85DCB8'), // 海绿色
        ColorUtils.fromHex('#F7DC6F')  // 柠檬黄
      ]
    ];
  }

  /**
   * 在趋势中寻找相似颜色
   */
  private findSimilarColorsInTrends(baseColor: Color, trendingPalettes: Color[][]): Color[] {
    const similarColors: Color[] = [];
    
    trendingPalettes.forEach(palette => {
      palette.forEach(color => {
        const similarity = this.calculateColorSimilarity(baseColor, color);
        if (similarity > 0.3) { // 相似度阈值
          similarColors.push(color);
        }
      });
    });
    
    return similarColors.slice(0, 4);
  }

  /**
   * 计算颜色相似度
   */
  private calculateColorSimilarity(color1: Color, color2: Color): number {
    const hsl1 = color1.hsl;
    const hsl2 = color2.hsl;
    
    // 计算HSL各分量的差异
    const hueDiff = Math.min(Math.abs(hsl1.h - hsl2.h), 360 - Math.abs(hsl1.h - hsl2.h)) / 180;
    const satDiff = Math.abs(hsl1.s - hsl2.s) / 100;
    const lightDiff = Math.abs(hsl1.l - hsl2.l) / 100;
    
    // 权重：色相最重要，其次是饱和度，最后是明度
    const similarity = 1 - (hueDiff * 0.5 + satDiff * 0.3 + lightDiff * 0.2);
    
    return Math.max(0, similarity);
  }

  /**
   * 获取当前季节
   */
  private getCurrentSeason(month: number): 'spring' | 'summer' | 'autumn' | 'winter' {
    if (month >= 2 && month <= 4) return 'spring';
    if (month >= 5 && month <= 7) return 'summer';
    if (month >= 8 && month <= 10) return 'autumn';
    return 'winter';
  }

  /**
   * 生成季节性颜色
   */
  private generateSeasonalColors(baseColor: Color, season: string): Color[] {
    const colors: Color[] = [];
    const hsl = baseColor.hsl;
    
    switch (season) {
      case 'spring':
        // 春季：清新、明亮的颜色
        colors.push(
          ColorUtils.fromHsl((hsl.h + 60) % 360, Math.max(60, hsl.s), Math.max(70, hsl.l)),
          ColorUtils.fromHsl((hsl.h + 120) % 360, Math.max(50, hsl.s - 10), Math.max(75, hsl.l)),
          ColorUtils.fromHsl((hsl.h + 30) % 360, Math.max(70, hsl.s), Math.max(80, hsl.l))
        );
        break;
      case 'summer':
        // 夏季：鲜艳、活力的颜色
        colors.push(
          ColorUtils.fromHsl((hsl.h + 180) % 360, Math.min(90, hsl.s + 20), Math.max(60, hsl.l)),
          ColorUtils.fromHsl((hsl.h + 45) % 360, Math.min(85, hsl.s + 15), Math.max(65, hsl.l)),
          ColorUtils.fromHsl((hsl.h + 90) % 360, Math.min(80, hsl.s + 10), Math.max(70, hsl.l))
        );
        break;
      case 'autumn':
        // 秋季：温暖、土色调
        colors.push(
          ColorUtils.fromHsl((hsl.h + 30) % 360, Math.max(60, hsl.s), Math.max(40, Math.min(60, hsl.l))),
          ColorUtils.fromHsl((hsl.h + 15) % 360, Math.max(65, hsl.s), Math.max(45, Math.min(65, hsl.l))),
          ColorUtils.fromHsl((hsl.h + 45) % 360, Math.max(55, hsl.s), Math.max(50, Math.min(70, hsl.l)))
        );
        break;
      case 'winter':
        // 冬季：冷色调、低饱和度
        colors.push(
          ColorUtils.fromHsl((hsl.h + 180) % 360, Math.max(30, hsl.s - 20), Math.max(30, Math.min(50, hsl.l))),
          ColorUtils.fromHsl((hsl.h + 200) % 360, Math.max(25, hsl.s - 25), Math.max(35, Math.min(55, hsl.l))),
          ColorUtils.fromHsl((hsl.h + 160) % 360, Math.max(35, hsl.s - 15), Math.max(40, Math.min(60, hsl.l)))
        );
        break;
    }
    
    return colors;
  }

  // 情绪相关的颜色生成方法
  
  private generateEnergeticColors(baseColor: Color): Color[] {
    // 高饱和度、明亮的颜色
    return [
      ColorUtils.adjustSaturation(ColorUtils.adjustLightness(baseColor, 20), 30),
      ColorUtils.fromHsl((baseColor.hsl.h + 60) % 360, 90, 70),
      ColorUtils.fromHsl((baseColor.hsl.h + 120) % 360, 85, 75)
    ];
  }

  private generateCalmColors(baseColor: Color): Color[] {
    // 低饱和度、中等明度的颜色
    return [
      ColorUtils.adjustSaturation(baseColor, -20),
      ColorUtils.fromHsl((baseColor.hsl.h + 30) % 360, 40, 60),
      ColorUtils.fromHsl((baseColor.hsl.h + 180) % 360, 35, 65)
    ];
  }

  private generateWarmColors(baseColor: Color): Color[] {
    // 暖色调范围的颜色
    const warmHues = [0, 30, 60, 300, 330]; // 红、橙、黄区域
    return warmHues.slice(0, 3).map(hue => 
      ColorUtils.fromHsl(hue, baseColor.hsl.s, baseColor.hsl.l)
    );
  }

  private generateCoolColors(baseColor: Color): Color[] {
    // 冷色调范围的颜色
    const coolHues = [180, 210, 240, 270]; // 青、蓝、紫区域
    return coolHues.slice(0, 3).map(hue => 
      ColorUtils.fromHsl(hue, baseColor.hsl.s, baseColor.hsl.l)
    );
  }

  private generateProfessionalColors(baseColor: Color): Color[] {
    // 专业、商务的颜色：中性、低饱和度
    return [
      ColorUtils.fromHsl(baseColor.hsl.h, 25, 40),
      ColorUtils.fromHsl((baseColor.hsl.h + 180) % 360, 20, 45),
      ColorUtils.fromHsl(0, 0, 50) // 灰色
    ];
  }

  private generatePlayfulColors(baseColor: Color): Color[] {
    // 活泼、有趣的颜色：高饱和度、明亮
    return [
      ColorUtils.fromHsl((baseColor.hsl.h + 120) % 360, 90, 80),
      ColorUtils.fromHsl((baseColor.hsl.h + 240) % 360, 85, 75),
      ColorUtils.fromHsl((baseColor.hsl.h + 60) % 360, 95, 85)
    ];
  }

  private getHueRange(hue: number): string {
    if (hue >= 0 && hue < 30) return 'red';
    if (hue >= 30 && hue < 60) return 'orange';
    if (hue >= 60 && hue < 90) return 'yellow';
    if (hue >= 90 && hue < 150) return 'green';
    if (hue >= 150 && hue < 210) return 'cyan';
    if (hue >= 210 && hue < 270) return 'blue';
    if (hue >= 270 && hue < 330) return 'purple';
    return 'magenta';
  }

  private getHueFromRange(range: string): number {
    const hueMap: { [key: string]: number } = {
      'red': 0,
      'orange': 30,
      'yellow': 60,
      'green': 120,
      'cyan': 180,
      'blue': 240,
      'purple': 300,
      'magenta': 330
    };
    return hueMap[range] || 0;
  }
}

// 用户偏好分析接口
interface UserPreferences {
  preferredHues: string[];
  averageSaturation: number;
  averageLightness: number;
  preferredSchemeTypes: string[];
}

// 导出单例实例
export const RecommendationEngine = ColorRecommendationEngine.getInstance();